package com.hhe.datax_transfer.service;

import cn.hutool.core.date.DateUtil;
import com.hhe.datax_transfer.cache.DataxJobMonitoringControl;
import com.hhe.datax_transfer.cache.ExecuteJobsQueue;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 监控操作
 *
 * @author HHe
 * @version V1.0
 * @date 2021/1/16 9:40
 */
@Slf4j
@Component
public class TransferMonitoring {
    @Resource
    private Executor taskExecutor;

    /**
     * 系统监控模板
     *
     * @return {@link Map< String, Object>}
     * @version V1.0
     * @author HHe
     * @date 2021/1/28 17:15
     */
    public Map<String, Object> importantSummariesModel() {
        return new LinkedHashMap<String, Object>(16) {{
            put("input", new HashMap<String, Object>(16) {{
                put("commitThreadPoolNum1", "提交任务数");
                put("finishThreadPoolNum1", "完成任务数");
                put("processingThreadPoolNum1", "正在执行线程数");
                put("usableQueueLength1", "当前可用队列长度");
                put("JVMMaxMemory", "JVM最大内存");
                put("JVMMemoryUsePercent", "JVM内存占用率");
            }});
            put("list", new HashMap<String, Object>(16) {{
                put("processingJobList", "正在执行文件列表");
                put("executeJobsQueueList", "准备执行队列列表");
                put("executeFinishLogs", "执行完成日志");
            }});
        }};
    }

    /**
     * 系统监控汇总
     *
     * @return {@link Map< String, Object>}
     * @version V1.0
     * @author HHe
     * @date 2021/1/25 19:52
     */
    public Map<String, Object> importantSummaries() {
        Map<String, Object> map = new HashMap<>(16);
        //I.线程池信息
        Object[] myThread = {taskExecutor};
        for (int i = 0; i < myThread.length; i++) {
            ThreadPoolTaskExecutor threadTask = (ThreadPoolTaskExecutor) myThread[i];
            ThreadPoolExecutor threadPoolExecutor = threadTask.getThreadPoolExecutor();
            //提交任务数
            map.put("commitThreadPoolNum" + (i + 1), threadPoolExecutor.getTaskCount());
            //完成任务数
            map.put("finishThreadPoolNum" + (i + 1), threadPoolExecutor.getCompletedTaskCount());
            //正在执行线程数
            map.put("processingThreadPoolNum" + (i + 1), threadPoolExecutor.getActiveCount());
            //当前可用队列长度
            map.put("usableQueueLength" + (i + 1), threadPoolExecutor.getQueue().remainingCapacity());
        }
        //II.系统信息
        int kb = 1024;
        long maxMemory = Runtime.getRuntime().maxMemory();
        long totalMemory = Runtime.getRuntime().totalMemory();
        map.put("JVMMaxMemory", maxMemory / kb / kb + "MB");
        log.info(totalMemory / kb / kb + "MB");
        map.put("JVMMemoryUsePercent", new DecimalFormat("0.00%").format(new BigDecimal(totalMemory).divide(new BigDecimal(maxMemory), 2, BigDecimal.ROUND_HALF_UP)));
        //III.执行任务数信息
        //正在执行文件列表
        map.put("processingJobList", DataxJobMonitoringControl.queryRunningJobList());
        map.put("executeJobsQueueList", ExecuteJobsQueue.getList());
        map.put("executeFinishLogs", DataxJobMonitoringControl.getRuningLogs());
        return map;
    }

    /**
     * 查询系统信息
     *
     * @version V1.0
     * @author HHe
     * @date 2021/1/16 9:47
     */
    public Map<String, Object> querySystemMess() {
        Map<String, Object> map = new HashMap<>(16);
        int kb = 1024;
        long totalMemory = Runtime.getRuntime().totalMemory() / kb / kb;
        long freeMemory = Runtime.getRuntime().freeMemory() / kb / kb;
        long maxMemory = Runtime.getRuntime().maxMemory() / kb / kb;
        log.info(totalMemory + "mb");
        log.info(freeMemory + "mb");
        log.info(maxMemory + "mb");
        return map;
    }

    /**
     * 查询执行线程池信息
     *
     * @version V1.0
     * @author HHe
     * @date 2021/1/16 9:49
     */
    public Map<String, Object> queryExecuteThreadPoolMess() {
        Map<String, Object> map = new HashMap<>(16);
        Object[] myThread = {taskExecutor};
        for (Object thread : myThread) {
            ThreadPoolTaskExecutor threadTask = (ThreadPoolTaskExecutor) thread;
            ThreadPoolExecutor threadPoolExecutor = threadTask.getThreadPoolExecutor();
            map.put("提交任务数-->", threadPoolExecutor.getTaskCount());
            map.put("完成任务数-->", threadPoolExecutor.getCompletedTaskCount());
            map.put("当前有多少线程正在处理任务-->", threadPoolExecutor.getActiveCount());
            map.put("还剩多少个任务未执行-->", threadPoolExecutor.getQueue().size());
            map.put("当前可用队列长度-->", threadPoolExecutor.getQueue().remainingCapacity());
            map.put("当前时间-->", DateUtil.now());
        }
        return map;
    }

    public void test() {
        Map map = new HashMap();
        Object[] myThread = {taskExecutor};
        for (Object thread : myThread) {
            ThreadPoolTaskExecutor threadTask = (ThreadPoolTaskExecutor) thread;
            ThreadPoolExecutor threadPoolExecutor = threadTask.getThreadPoolExecutor();
            System.out.println("提交任务数" + threadPoolExecutor.getTaskCount());
            System.out.println("完成任务数" + threadPoolExecutor.getCompletedTaskCount());
            System.out.println("当前有" + threadPoolExecutor.getActiveCount() + "个线程正在处理任务");
            System.out.println("还剩" + threadPoolExecutor.getQueue().size() + "个任务");
            map.put("提交任务数-->", threadPoolExecutor.getTaskCount());
            map.put("完成任务数-->", threadPoolExecutor.getCompletedTaskCount());
            map.put("当前有多少线程正在处理任务-->", threadPoolExecutor.getActiveCount());
            map.put("还剩多少个任务未执行-->", threadPoolExecutor.getQueue().size());
            map.put("当前可用队列长度-->", threadPoolExecutor.getQueue().remainingCapacity());
            map.put("当前时间-->", DateUtil.now());
        }
        System.out.println(map);
    }

}
